"""
持久化服务

提供策略执行数据的持久化功能，集成到现有策略系统中
"""

import time
from typing import Dict, Any, List, Optional
from datetime import datetime, date
from threading import Thread, Event
import queue

from .database_manager import DatabaseManager
from ..core import unified_logger


class PersistenceService:
    """持久化服务"""
    
    def __init__(self, database_url: Optional[str] = None):
        """
        初始化持久化服务
        
        Args:
            database_url: 数据库连接URL
        """
        self.logger = unified_logger.get_logger('persistence_service')
        self.db_manager = DatabaseManager(database_url)
        
        # 异步处理队列
        self.data_queue = queue.Queue()
        self.worker_thread = None
        self.stop_event = Event()
        self.running = False
        
        # 缓存策略ID映射
        self.strategy_id_cache = {}
        
    def start(self):
        """启动持久化服务"""
        if self.running:
            return
        
        self.running = True
        self.stop_event.clear()
        
        # 启动工作线程
        self.worker_thread = Thread(target=self._worker_loop, daemon=True)
        self.worker_thread.start()
        
        self.logger.info("持久化服务已启动")
    
    def stop(self):
        """停止持久化服务"""
        if not self.running:
            return
        
        self.running = False
        self.stop_event.set()
        
        # 等待工作线程结束
        if self.worker_thread and self.worker_thread.is_alive():
            self.worker_thread.join(timeout=5)
        
        self.logger.info("持久化服务已停止")
    
    def _worker_loop(self):
        """工作线程循环"""
        while not self.stop_event.is_set():
            try:
                # 从队列获取数据
                try:
                    data_item = self.data_queue.get(timeout=1)
                except queue.Empty:
                    continue
                
                # 处理数据
                self._process_data_item(data_item)
                self.data_queue.task_done()
                
            except Exception as e:
                self.logger.error(f"持久化工作线程错误: {e}")
    
    def _process_data_item(self, data_item: Dict[str, Any]):
        """处理数据项"""
        try:
            data_type = data_item.get('type')
            data = data_item.get('data')
            
            if data_type == 'strategy':
                self._save_strategy_data(data)
            elif data_type == 'order':
                self._save_order_data(data)
            elif data_type == 'trade':
                self._save_trade_data(data)
            elif data_type == 'performance':
                self._save_performance_data(data)
            elif data_type == 'backtest':
                self._save_backtest_data(data)
            elif data_type == 'balance':
                self._save_balance_data(data)
            elif data_type == 'alert':
                self._save_alert_data(data)
            elif data_type == 'data_file':
                self._save_data_file_info(data)
            else:
                self.logger.warning(f"未知数据类型: {data_type}")
                
        except Exception as e:
            self.logger.error(f"处理数据项失败: {e}")
    
    def _save_strategy_data(self, data: Dict[str, Any]):
        """保存策略数据"""
        try:
            strategy_name = data.get('name')
            if strategy_name in self.strategy_id_cache:
                # 更新现有策略
                strategy_id = self.strategy_id_cache[strategy_name]
                self.db_manager.update_strategy(strategy_id, data)
            else:
                # 创建新策略
                strategy_id = self.db_manager.create_strategy(data)
                self.strategy_id_cache[strategy_name] = strategy_id
                
        except Exception as e:
            self.logger.error(f"保存策略数据失败: {e}")
    
    def _save_order_data(self, data: Dict[str, Any]):
        """保存订单数据"""
        try:
            # 获取策略ID
            strategy_name = data.get('strategy')
            if strategy_name and strategy_name in self.strategy_id_cache:
                data['strategy_id'] = self.strategy_id_cache[strategy_name]
            
            # 检查是否已存在
            order_id = data.get('order_id')
            if order_id:
                # 尝试更新
                success = self.db_manager.update_order(order_id, data)
                if not success:
                    # 创建新订单
                    data['id'] = order_id
                    self.db_manager.create_order(data)
            else:
                # 创建新订单
                self.db_manager.create_order(data)
                
        except Exception as e:
            self.logger.error(f"保存订单数据失败: {e}")
    
    def _save_trade_data(self, data: Dict[str, Any]):
        """保存交易数据"""
        try:
            # 获取策略ID
            strategy_name = data.get('strategy')
            if strategy_name and strategy_name in self.strategy_id_cache:
                data['strategy_id'] = self.strategy_id_cache[strategy_name]
            
            self.db_manager.create_trade(data)
            
        except Exception as e:
            self.logger.error(f"保存交易数据失败: {e}")
    
    def _save_performance_data(self, data: Dict[str, Any]):
        """保存性能数据"""
        try:
            # 获取策略ID
            strategy_name = data.get('strategy_name')
            if strategy_name and strategy_name in self.strategy_id_cache:
                data['strategy_id'] = self.strategy_id_cache[strategy_name]
            
            self.db_manager.save_strategy_performance(data)
            
        except Exception as e:
            self.logger.error(f"保存性能数据失败: {e}")
    
    def _save_backtest_data(self, data: Dict[str, Any]):
        """保存回测数据"""
        try:
            self.db_manager.save_backtest_result(data)
            
        except Exception as e:
            self.logger.error(f"保存回测数据失败: {e}")
    
    def _save_balance_data(self, data: Dict[str, Any]):
        """保存余额数据"""
        try:
            self.db_manager.update_account_balance(data)
            
        except Exception as e:
            self.logger.error(f"保存余额数据失败: {e}")
    
    def _save_alert_data(self, data: Dict[str, Any]):
        """保存告警数据"""
        try:
            # 获取策略ID
            strategy_name = data.get('strategy_name')
            if strategy_name and strategy_name in self.strategy_id_cache:
                data['strategy_id'] = self.strategy_id_cache[strategy_name]
            
            self.db_manager.create_alert(data)
            
        except Exception as e:
            self.logger.error(f"保存告警数据失败: {e}")
    
    def _save_data_file_info(self, data: Dict[str, Any]):
        """保存数据文件信息"""
        try:
            self.db_manager.record_data_file(data)
            
        except Exception as e:
            self.logger.error(f"保存数据文件信息失败: {e}")
    
    # 公共接口方法
    def save_strategy(self, strategy_data: Dict[str, Any]):
        """
        保存策略数据
        
        Args:
            strategy_data: 策略数据
        """
        self.data_queue.put({
            'type': 'strategy',
            'data': strategy_data
        })
    
    def save_order(self, order_data: Dict[str, Any]):
        """
        保存订单数据
        
        Args:
            order_data: 订单数据
        """
        self.data_queue.put({
            'type': 'order',
            'data': order_data
        })
    
    def save_trade(self, trade_data: Dict[str, Any]):
        """
        保存交易数据
        
        Args:
            trade_data: 交易数据
        """
        self.data_queue.put({
            'type': 'trade',
            'data': trade_data
        })
    
    def save_performance(self, performance_data: Dict[str, Any]):
        """
        保存性能数据
        
        Args:
            performance_data: 性能数据
        """
        self.data_queue.put({
            'type': 'performance',
            'data': performance_data
        })
    
    def save_backtest_result(self, backtest_data: Dict[str, Any]):
        """
        保存回测结果
        
        Args:
            backtest_data: 回测数据
        """
        self.data_queue.put({
            'type': 'backtest',
            'data': backtest_data
        })
    
    def save_account_balance(self, balance_data: Dict[str, Any]):
        """
        保存账户余额
        
        Args:
            balance_data: 余额数据
        """
        self.data_queue.put({
            'type': 'balance',
            'data': balance_data
        })
    
    def save_alert(self, alert_data: Dict[str, Any]):
        """
        保存告警数据
        
        Args:
            alert_data: 告警数据
        """
        self.data_queue.put({
            'type': 'alert',
            'data': alert_data
        })
    
    def save_data_file(self, file_data: Dict[str, Any]):
        """
        保存数据文件信息
        
        Args:
            file_data: 文件数据
        """
        self.data_queue.put({
            'type': 'data_file',
            'data': file_data
        })
    
    # 查询接口
    def get_strategy(self, strategy_id: str) -> Optional[Dict[str, Any]]:
        """获取策略数据"""
        return self.db_manager.get_strategy(strategy_id)
    
    def list_strategies(self, status: Optional[str] = None) -> List[Dict[str, Any]]:
        """获取策略列表"""
        return self.db_manager.list_strategies(status)
    
    def get_orders_by_strategy(self, strategy_id: str, limit: int = 100) -> List[Dict[str, Any]]:
        """获取策略订单"""
        return self.db_manager.get_orders_by_strategy(strategy_id, limit)
    
    def get_trades_by_strategy(self, strategy_id: str, limit: int = 100) -> List[Dict[str, Any]]:
        """获取策略交易记录"""
        return self.db_manager.get_trades_by_strategy(strategy_id, limit)
    
    def get_strategy_performance(self, strategy_id: str, days: int = 30) -> List[Dict[str, Any]]:
        """获取策略性能记录"""
        return self.db_manager.get_strategy_performance(strategy_id, days)
    
    def get_backtest_results(self, strategy_name: Optional[str] = None, limit: int = 50) -> List[Dict[str, Any]]:
        """获取回测结果"""
        return self.db_manager.get_backtest_results(strategy_name, limit)
    
    def get_account_balances(self, exchange: Optional[str] = None) -> List[Dict[str, Any]]:
        """获取账户余额"""
        return self.db_manager.get_account_balances(exchange)
    
    def get_active_alerts(self, limit: int = 100) -> List[Dict[str, Any]]:
        """获取活跃告警"""
        return self.db_manager.get_active_alerts(limit)
    
    def get_data_files(self, exchange: Optional[str] = None, symbol: Optional[str] = None) -> List[Dict[str, Any]]:
        """获取数据文件列表"""
        return self.db_manager.get_data_files(exchange, symbol)
    
    def get_database_stats(self) -> Dict[str, Any]:
        """获取数据库统计"""
        return self.db_manager.get_database_stats()
    
    def cleanup_old_data(self, days: int = 90) -> int:
        """清理旧数据"""
        return self.db_manager.cleanup_old_data(days)


# 全局持久化服务实例
_persistence_service = None


def get_persistence_service(database_url: Optional[str] = None) -> PersistenceService:
    """
    获取持久化服务实例（单例模式）
    
    Args:
        database_url: 数据库连接URL
        
    Returns:
        持久化服务实例
    """
    global _persistence_service
    
    if _persistence_service is None:
        _persistence_service = PersistenceService(database_url)
        _persistence_service.start()
    
    return _persistence_service


def init_persistence_service(database_url: Optional[str] = None):
    """
    初始化持久化服务
    
    Args:
        database_url: 数据库连接URL
    """
    global _persistence_service
    
    if _persistence_service is not None:
        _persistence_service.stop()
    
    _persistence_service = PersistenceService(database_url)
    _persistence_service.start()


def stop_persistence_service():
    """停止持久化服务"""
    global _persistence_service
    
    if _persistence_service is not None:
        _persistence_service.stop()
        _persistence_service = None